(function(c) {
    var b = mobiscroll,
        a = b.$,
        d = {
            autostart: false,
            step: 1,
            useShortLabels: false,
            labels: ['Years', 'Months', 'Days', 'Hours', 'Minutes', 'Seconds', ''],
            labelsShort: ['Yrs', 'Mths', 'Days', 'Hrs', 'Mins', 'Secs', ''],
            startText: 'Start',
            stopText: 'Stop',
            resetText: 'Reset',
            lapText: 'Lap',
            hideText: 'Hide'
        };
    b.presetShort('timer');
    b.presets.scroller.timer = function(b) {
        function I(a) {
            return new Date(a.getUTCFullYear(), a.getUTCMonth(), a.getUTCDate(), a.getUTCHours(), a.getUTCMinutes(), a.getUTCSeconds(), a.getUTCMilliseconds());
        }

        function N(n) {
            var b = {};
            if (C && i[m].index > i.days.index) {
                var f, e, o, g, h = new Date(),
                    c = k ? h : l,
                    d = k ? l : h;
                d = I(d);
                c = I(c);
                b.years = c.getFullYear() - d.getFullYear();
                b.months = c.getMonth() - d.getMonth();
                b.days = c.getDate() - d.getDate();
                b.hours = c.getHours() - d.getHours();
                b.minutes = c.getMinutes() - d.getMinutes();
                b.seconds = c.getSeconds() - d.getSeconds();
                b.fract = (c.getMilliseconds() - d.getMilliseconds()) / 10;
                for (f = j.length; f > 0; f--) {
                    e = j[f - 1];
                    o = i[e];
                    g = j[a.inArray(e, j) - 1];
                    if (i[g] && b[e] < 0) {
                        b[g]--;
                        b[e] += g == 'months' ? 32 - new Date(c.getFullYear(), c.getMonth(), 32).getDate() : o.until + 1;
                    }
                }
                if (m == 'months') {
                    b.months += b.years * 12;
                    delete b.years;
                }
            } else {
                a(j).each(function(c, a) {
                    if (i[a].index <= i[m].index) {
                        b[a] = Math.floor(n / i[a].limit);
                        n -= b[a] * i[a].limit;
                    }
                });
            }
            return b;
        }

        function M(d) {
            var e = 1,
                b = i[d],
                c = b.wheel,
                f = b.prefix,
                h = 0,
                k = b.until,
                g = i[j[a.inArray(d, j) - 1]];
            if (b.index <= i[m].index && (!g || g.limit > x)) {
                if (!p[d]) {
                    H[0].push(c);
                }
                p[d] = 1;
                c.data = [];
                c.label = b.label || '';
                c.cssClass = 'mbsc-timer-whl-' + d;
                if (x >= b.limit) {
                    e = Math.max(Math.round(x / b.limit), 1);
                    v = e * b.limit;
                }
                if (d == m) {
                    c.min = 0;
                    c.data = function(a) {
                        return {
                            value: a,
                            display: K(a, f, b.label)
                        };
                    };
                    c.getIndex = function(a) {
                        return a;
                    };
                } else {
                    for (y = h; y <= k; y += e) {
                        c.data.push({
                            value: y,
                            display: K(y, f, b.label)
                        });
                    }
                }
            }
        }

        function K(a, b, c) {
            return (b || '') + (a < 10 ? '0' : '') + a + '<span class="mbsc-timer-lbl">' + c + '</span>';
        }

        function r(e) {
            var b = [],
                c, d = N(e);
            a(j).each(function(e, a) {
                if (p[a]) {
                    c = Math.max(Math.round(x / i[a].limit), 1);
                    b.push(Math.round(d[a] / c) * c);
                }
            });
            return b;
        }

        function G(a) {
            if (C) {
                g = l - new Date();
                if (g < 0) {
                    g *= -1;
                    k = true;
                } else {
                    k = false;
                }
                f = 0;
                t = true;
            } else if (l !== c) {
                t = false;
                g = l * 1000;
                k = e.mode != 'countdown';
                if (a) {
                    f = 0;
                }
            } else {
                g = 0;
                k = e.mode != 'countdown';
                t = k;
                if (a) {
                    f = 0;
                }
            }
        }

        function F() {
            if (n) {
                a('.mbsc-fr-w', h).addClass('mbsc-timer-running mbsc-timer-locked');
                a('.mbsc-timer-btn-toggle-c > div', h).text(e.stopText);
                if (b.buttons.start.icon) {
                    a('.mbsc-timer-btn-toggle-c > div', h).removeClass('mbsc-ic-' + b.buttons.start.icon);
                }
                if (b.buttons.stop.icon) {
                    a('.mbsc-timer-btn-toggle-c > div', h).addClass('mbsc-ic-' + b.buttons.stop.icon);
                }
                if (e.mode == 'stopwatch') {
                    a('.mbsc-timer-btn-resetlap-c > div', h).text(e.lapText);
                    if (b.buttons.reset.icon) {
                        a('.mbsc-timer-btn-resetlap-c > div', h).removeClass('mbsc-ic-' + b.buttons.reset.icon);
                    }
                    if (b.buttons.lap.icon) {
                        a('.mbsc-timer-btn-resetlap-c > div', h).addClass('mbsc-ic-' + b.buttons.lap.icon);
                    }
                }
            } else {
                a('.mbsc-fr-w', h).removeClass('mbsc-timer-running');
                a('.mbsc-timer-btn-toggle-c > div', h).text(e.startText);
                if (b.buttons.start.icon) {
                    a('.mbsc-timer-btn-toggle-c > div', h).addClass('mbsc-ic-' + b.buttons.start.icon);
                }
                if (b.buttons.stop.icon) {
                    a('.mbsc-timer-btn-toggle-c > div', h).removeClass('mbsc-ic-' + b.buttons.stop.icon);
                }
                if (e.mode == 'stopwatch') {
                    a('.mbsc-timer-btn-resetlap-c > div', h).text(e.resetText);
                    if (b.buttons.reset.icon) {
                        a('.mbsc-timer-btn-resetlap-c > div', h).addClass('mbsc-ic-' + b.buttons.reset.icon);
                    }
                    if (b.buttons.lap.icon) {
                        a('.mbsc-timer-btn-resetlap-c > div', h).removeClass('mbsc-ic-' + b.buttons.lap.icon);
                    }
                }
            }
        }
        var y, D, v, s, u, w, g, f, k, h, L, J = a.extend({}, b.settings),
            e = a.extend(b.settings, d, J),
            o = e.useShortLabels ? e.labelsShort : e.labels,
            E = ['toggle', 'resetlap'],
            j = ['years', 'months', 'days', 'hours', 'minutes', 'seconds', 'fract'],
            i = {
                'years': {
                    index: 6,
                    until: 10,
                    limit: 1000 * 60 * 60 * 24 * 365,
                    label: o[0],
                    wheel: {}
                },
                'months': {
                    index: 5,
                    until: 11,
                    limit: 1000 * 60 * 60 * 24 * 30,
                    label: o[1],
                    wheel: {}
                },
                'days': {
                    index: 4,
                    until: 31,
                    limit: 1000 * 60 * 60 * 24,
                    label: o[2],
                    wheel: {}
                },
                'hours': {
                    index: 3,
                    until: 23,
                    limit: 1000 * 60 * 60,
                    label: o[3],
                    wheel: {}
                },
                'minutes': {
                    index: 2,
                    until: 59,
                    limit: 1000 * 60,
                    label: o[4],
                    wheel: {}
                },
                'seconds': {
                    index: 1,
                    until: 59,
                    limit: 1000,
                    label: o[5],
                    wheel: {}
                },
                'fract': {
                    index: 0,
                    until: 99,
                    limit: 10,
                    label: o[6],
                    prefix: '.',
                    wheel: {}
                }
            },
            p = {},
            A = [],
            B = 0,
            n = false,
            q = true,
            t = false,
            x = Math.max(10, e.step * 1000),
            m = e.maxWheel,
            z = e.mode == 'stopwatch' || C,
            l = e.targetTime,
            C = l && l.getTime !== c,
            H = [
                []
            ];
        b.start = function() {
            if (q) {
                b.reset();
            }
            if (!n) {
                G();
                if (!t && f >= g) {
                    return;
                }
                n = true;
                q = false;
                u = new Date();
                s = f;
                e.readonly = true;
                b.setVal(r(k ? f : g - f), true, true, false, 100);
                D = setInterval(function() {
                    f = new Date() - u + s;
                    b.setVal(r(k ? f : g - f), true, true, false, Math.min(100, v - 10));
                    if (!t && f + v >= g) {
                        clearInterval(D);
                        setTimeout(function() {
                            b.stop();
                            f = g;
                            b.setVal(r(k ? f : 0), true, true, false, 100);
                            b.trigger('onFinish', {
                                time: g
                            });
                            q = true;
                        }, g - f);
                    }
                }, v);
                F();
                b.trigger('onStart');
            }
        };
        b.stop = function() {
            if (n) {
                n = false;
                clearInterval(D);
                f = new Date() - u + s;
                F();
                b.trigger('onStop', {
                    ellapsed: f
                });
            }
        };
        b.toggle = function() {
            if (n) {
                b.stop();
            } else {
                b.start();
            }
        };
        b.reset = function() {
            b.stop();
            f = 0;
            A = [];
            B = 0;
            b.setVal(r(k ? 0 : g), true, true, false, 100);
            b.settings.readonly = z;
            q = true;
            if (!z) {
                a('.mbsc-fr-w', h).removeClass('mbsc-timer-locked');
            }
            b.trigger('onReset');
        };
        b.lap = function() {
            if (n) {
                w = new Date() - u + s;
                L = w - B;
                B = w;
                A.push(w);
                b.trigger('onLap', {
                    ellapsed: w,
                    lap: L,
                    laps: A
                });
            }
        };
        b.resetlap = function() {
            if (n && e.mode == 'stopwatch') {
                b.lap();
            } else {
                b.reset();
            }
        };
        b.getTime = function() {
            return g;
        };
        b.setTime = function(a) {
            l = a / 1000;
            g = a;
        };
        b.getElapsedTime = b.getEllapsedTime = function() {
            return n ? new Date() - u + s : 0;
        };
        b.setElapsedTime = b.setEllapsedTime = function(a, c) {
            if (!q) {
                s = f = a;
                u = new Date();
                b.setVal(r(k ? f : g - f), true, c, false, 100);
            }
        };
        G(true);
        if (!m && !g) {
            m = 'minutes';
        }
        if (e.display !== 'inline') {
            E.push('hide');
        }
        if (!m) {
            a(j).each(function(b, a) {
                if (!m && g >= i[a].limit) {
                    m = a;
                    return false;
                }
            });
        }
        a(j).each(function(b, a) {
            M(a);
        });
        v = Math.max(87, v);
        if (e.autostart) {
            setTimeout(function() {
                b.start();
            }, 0);
        }
        b.handlers.toggle = b.toggle;
        b.handlers.start = b.start;
        b.handlers.stop = b.stop;
        b.handlers.resetlap = b.resetlap;
        b.handlers.reset = b.reset;
        b.handlers.lap = b.lap;
        b.buttons.toggle = {
            parentClass: 'mbsc-timer-btn-toggle-c',
            text: e.startText,
            handler: 'toggle'
        };
        b.buttons.start = {
            text: e.startText,
            handler: 'start'
        };
        b.buttons.stop = {
            text: e.stopText,
            handler: 'stop'
        };
        b.buttons.reset = {
            text: e.resetText,
            handler: 'reset'
        };
        b.buttons.lap = {
            text: e.lapText,
            handler: 'lap'
        };
        b.buttons.resetlap = {
            parentClass: 'mbsc-timer-btn-resetlap-c',
            text: e.resetText,
            handler: 'resetlap'
        };
        b.buttons.hide = {
            parentClass: 'mbsc-timer-btn-hide-c',
            text: e.hideText,
            handler: 'cancel'
        };
        return {
            wheels: H,
            headerText: false,
            readonly: z,
            buttons: E,
            mode: 'countdown',
            compClass: 'mbsc-timer',
            parseValue: function() {
                return r(k ? 0 : g);
            },
            formatValue: function(d) {
                var c = '',
                    b = 0;
                a(j).each(function(e, a) {
                    if (a == 'fract') {
                        return;
                    }
                    if (p[a]) {
                        c += d[b] + (a == 'seconds' && p.fract ? '.' + d[b + 1] : '') + ' ' + o[e] + ' ';
                        b++;
                    }
                });
                return c;
            },
            validate: function(d) {
                var e = d.values,
                    f = d.index,
                    b = 0;
                if (q && f !== c) {
                    l = 0;
                    a(j).each(function(c, a) {
                        if (p[a]) {
                            l += i[a].limit * e[b];
                            b++;
                        }
                    });
                    l /= 1000;
                    G(true);
                }
            },
            onBeforeShow: function() {
                e.showLabel = true;
            },
            onMarkupReady: function(b) {
                h = a(b.target);
                F();
                if (z) {
                    a('.mbsc-fr-w', h).addClass('mbsc-timer-locked');
                }
            },
            onPosition: function(b) {
                a('.mbsc-fr-w', b.target).css('min-width', 0).css('min-width', a('.mbsc-fr-btn-cont', b.target)[0].offsetWidth);
            },
            onDestroy: function() {
                clearInterval(D);
            }
        };
    };
}());